import React, { useState, useEffect, useMemo, useCallback, useRef } from 'react';
import styles from './index.css';
import { formatMessage } from 'umi-plugin-locale';
export default function () {
  // const [count, setCount] = useState(0);
  // const [val, setVal] = useState('');
  // useEffect(() => {
  //   console.log('effect1');
  //   return () => {
  //     console.log('return1');
  //   };
  // }, [val]);

  // const callback = useCallback(() => {
  //   return count;
  // }, [count]);

  // //   function expensive() {
  // //     console.log('compute');
  // //     let sum = 0;
  // //     for (let i = 0; i < count * 100; i++) {
  // //         sum += i;
  // //     }
  // //     return sum;
  // // }

  // const expensive = useMemo(() => {
  //   console.log('compute');
  //   let sum = 0;
  //   for (let i = 0; i < count * 100; i++) {
  //     sum += i;
  //   }
  //   return sum;
  // }, [count]);

  // return (
  //   <div>
  //     {count}....{val}....{expensive}
  //     <Child callback={callback}></Child>
  //     <button
  //       onClick={() => {
  //         setCount(count + 1);
  //       }}
  //     >
  //       count
  //     </button>
  //     <button
  //       onClick={() => {
  //         setVal(val + 'S');
  //       }}
  //     >
  //       val
  //     </button>
  //   </div>
  // );

  interface Iname {
    (): void
    name: string
  }

  const ttt111: Iname = () => {

  }

  console.log(ttt111.name)




  type ItestType<P = string> = Itest<P>
  interface Itest<P = number> {
    (a: P, b: P): P;
    nameaaa: P;
  }
  const x: ItestType<number> = ((a, b) => a + b) as ItestType<number>
  // x.nameaaa = 1

  const [count, setCount] = useState(1);
  const [val, setVal] = useState('');

  const callback = useCallback(() => {
    return count;
  }, [count]);
  // function callback() {
  //   return count;
  // }
  return (
    <div>
      <h4>{count}</h4>
      <Child callback={callback} />
      <div>
        <button onClick={() => setCount(count + 1)}>+</button>
        <input value={val} onChange={event => setVal(event.target.value)} />
      </div>
      <Counter></Counter>
    </div>
  );
}

function Child({ callback }: any) {
  const [count, setCount] = useState(() => callback());
  useEffect(() => {
    console.log('child');
    setCount(callback());
  }, [callback]);
  return <div>{count}</div>;
}

function Counter() {
  const [count, setCount] = useState(0);
  let [delay, setDelay] = useState<number | undefined>(1000);

  // useEffect(() => {
  //   const id = setInterval(() => {
  //     setCount(count + 1);
  //   }, 1000);
  //   // 返回一个清理副作用的函数
  //   return () => {
  //     clearInterval(id);
  //   };
  // }, [count]);
  function handleDelayChange(e: React.ChangeEvent<HTMLInputElement>) {
    setDelay(e.target.value ? Number(e.target.value) : undefined);
  }
  useInterval(
    () => {
      setCount(count + 1);
      console.log(count);
    },
    delay,
    count,
  );
  // console.log(count);
  return (
    <div>
      <h1>{count}</h1>
      <input
        value={delay}
        onChange={e => {
          handleDelayChange(e);
        }}
      />
    </div>
  );
}

// useInterval 目前最好的实现方式
function useInterval(callback: Function, delay?: number, count?: number) {
  const savedCallback = useRef<Function>();
  console.log(count);

  useEffect(() => {
    savedCallback.current = callback;
  });

  // 因为存在闭包导致且该useEffect只与delay挂钩，所以在tick内 callback无法更新，
  // 使用useRef 把callback挂在savedCallback下既可解决tick内callback不更新的问题。
  // 若tick内直接使用callback，该useEffect也可与count挂钩也可实现预期功能，但是count变化过于频繁，会频繁的setInterval和clearInterval，并不理想
  useEffect(() => {
    console.log('tick');
    function tick() {
      savedCallback.current && savedCallback.current();
    }
    if (delay !== undefined) {
      let id = setInterval(tick, delay);
      console.log('return');
      return () => clearInterval(id);
    }
  }, [delay]);
}

console.log('test2')
